'''
pygeom -- Python Geometric Engine
point -- Definition of the Point

The point is a GE that has only a position (Point.pos) and no dimension.
It constitutes the only 0-dimensional GE.
'''

from pygeom import ge
from pygeom import cls
from pygeom import constraint
from pygeom import vector
from pygeom import intersect

class Point(ge.GE):
    def __init__(self, x, y, z):
        ge.GE.__init__(self)
        self.pos=(x, y, z)
        self._cls=(cls.POINT,)
    @classmethod
    def FromTuple(kls, pos, *args, **kwargs):
        return kls(pos[0], pos[1], pos[2], *args, **kwargs)
    @classmethod
    def FromVector(kls, vec, *args, **kwargs):
        return kls(vec.x, vec.y, vec.z, *args, **kwargs)
    def __repr__(self):
        return'Point(%s, %s, %s)'%(self.X, self.Y, self.Z)
    def _get_X(self):
        return self.pos[0]
    def _set_X(self, val):
        self.pos[0]=val
    def _get_Y(self):
        return self.pos[1]
    def _set_Y(self, val):
        self.pos[1]=val
    def _get_Z(self):
        return self.pos[2]
    def _set_Z(self, val):
        self.pos[2]=val
    X=property(_get_X, _set_X)
    Y=property(_get_Y, _set_Y)
    Z=property(_get_Z, _set_Z)
    @property
    def Vector(self):
        return vector.Vector(self.X, self.Y, self.Z)
    #Override some GE methods
    def _ConSetup(self):
        self._ConDefine(constraint.CON.COINCIDENT, (self._ForceCoincident,), (self._CheckCoincident,),
                         ((cls.POINT, cls.LINE, cls.PLANE),))
    def _CheckCoincident(self, ge):
        if cls.Check(ge.Class, cls.POINT):
            return self.pos==ge.pos
        elif cls.Check(ge.Class, cls.LINE, cls.PLANE):
            return self.pos==ge.ClosestPoint(self).pos
        else:
            return False
    def _ForceCoincident(self, ge):
        if cls.POINT in ge.Class:
            self.pos=ge.pos
            return True
        elif cls.LINE in ge.Class or cls.PLANE in ge.Class:
            self.pos=ge.ClosestPoint(self).pos
            return True
        else:
            return False
    def _IsctSetup(self):
        self._IsctMode(intersect.DEFER_ALL|
                       intersect.CLS_POINT) #Other classes define more intersections
    def _IsctPoint(self, pt):
        if self.pos==pt.pos:
            return self
        return None
